#include <chrono>  // 包含用于处理时间的库
#include <memory>  // 包含智能指针库
#include <string>  // 包含字符串库
#include <thread>  // 包含线程库
#include <utility> // 包含实用工具库

#include "rclcpp/rclcpp.hpp"                        // 包含ROS 2客户端库
#include "rclcpp_lifecycle/lifecycle_node.hpp"      // 包含生命周期节点库
#include "lifecycle_msgs/msg/transition.hpp"        // 包含生命周期消息中的转换消息
#include "rclcpp_lifecycle/lifecycle_publisher.hpp" // 包含生命周期发布者库
#include "rclcpp_action/rclcpp_action.hpp"

#include "std_msgs/msg/string.hpp"
#include "basic_lifecycle.h"

using namespace std::chrono_literals;

class BasicCmd : public test_utils::BasicLifecycleNode
{
public:
    explicit BasicCmd(const std::string &node_name, bool intra_process_comms = false)
        : test_utils::BasicLifecycleNode(node_name,rclcpp::NodeOptions().use_intra_process_comms(intra_process_comms)) // 初始化父类LifecycleNode
    {
    }

    void publish()
    {
        static size_t count = 0;                                        // 静态计数器
        auto msg = std::make_unique<std_msgs::msg::String>();           // 创建一个唯一指针的字符串消息
        msg->data = "Lifecycle HelloWorld #" + std::to_string(++count); // 设置消息内容

        if (!pub_->is_activated())
        {
            // 如果发布者未激活，打印信息
            RCLCPP_INFO(this->get_logger(), "Lifecycle publisher is currently inactive. Messages are not published."); 
        }
        else
        {
            // 如果发布者已激活，打印并发布信息
            RCLCPP_INFO(this->get_logger(), "Lifecycle publisher is active. Publishing: [%s]", msg->data.c_str());
        }

        // 我们在任何状态下都调用生命周期发布者的发布函数。
        // 只有在发布者处于激活状态时，消息传输才会启用并且消息实际发布。
        pub_->publish(std::move(msg));
    }

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_configure(const rclcpp_lifecycle::State &)
    {
        pub_ = this->create_publisher<std_msgs::msg::String>("lifecycle_chatter", 10);
        this->timer_ = this->create_wall_timer(std::chrono::milliseconds(500), std::bind(&BasicCmd::publish, this));

        RCLCPP_INFO(this->get_logger(), "on_configure() is called.");
        return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
    }

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_activate(const rclcpp_lifecycle::State &state)
    {
        // 父类方法自动在托管实体（目前是LifecyclePublisher）上过渡。
        // 这里也可以手动调用pub_->on_activate()。
        // 重写此方法是可选的，很多时候默认方法就足够了。
        LifecycleNode::on_activate(state);

        RCLCPP_INFO(this->get_logger(), "on_activate() is called.");
        return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
    }

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_deactivate(const rclcpp_lifecycle::State &state)
    {
        LifecycleNode::on_deactivate(state);

        RCLCPP_INFO(this->get_logger(), "on_deactivate() is called.");
        return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
    }

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_cleanup(const rclcpp_lifecycle::State &)
    {
        // 在我们的清理阶段，我们释放定时器和发布者的共享指针。这些实体不再可用，我们的节点是“干净”的。
        pub_.reset();

        RCLCPP_INFO(this->get_logger(), "on cleanup is called.");
        return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
    }

    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
    on_shutdown(const rclcpp_lifecycle::State &state)
    {
        // 在我们的关闭阶段，我们释放定时器和发布者的共享指针。这些实体不再可用，我们的节点是“干净”的。
        pub_.reset();

        RCLCPP_INFO(this->get_logger(), "on shutdown is called from state %s.", state.label().c_str());
        return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
    }

private:
    // 我们持有一个生命周期发布者的实例。根据生命周期节点所处的状态，此生命周期发布者可以被激活或停用。
    // 默认情况下，生命周期发布者在创建时是未激活的，必须激活才能将消息发布到ROS世界。
    std::shared_ptr<rclcpp_lifecycle::LifecyclePublisher<std_msgs::msg::String>> pub_;
    rclcpp::TimerBase::SharedPtr timer_;
};